20543
12866
Ik heb een lijst met tijden in seconden, zoals:
L = [0.10218048, 1.20851996, 1.46800021, 1.73429061, 2.71525848,
3.14781922, 3.63637958, 5.11147358, 5.97497864, 6.35469013,
6.80623747, 6.99571917, 7.65215123, 7.86108352, 8.52988247,
8.83068894, 10.07690977, 11.53867284, 12.01214112, 12.13307653]
Voor elk venster met een lengte van 2 seconden, beginnend bij een tweede grens, wil ik een lijst uitvoeren met alle tijden die binnen het venster van 2 seconden vallen. Dus voor het bovenstaande voorbeeld zou het zijn:
[0.10218048, 1.20851996, 1.46800021, 1.73429061]
[1.20851996, 1.46800021, 1.73429061, 2.71525848]
[2.71525848, 3.14781922, 3.63637958]
[3.14781922, 3.63637958]
[5.11147358, 5.97497864]
[5.11147358, 5.97497864, 6.35469013, 6.80623747, 6.99571917]
[6.35469013, 6.80623747, 6.99571917, 7.65215123, 7.86108352]
[7.65215123, 7.86108352, 8.52988247, 8.83068894]
[8.52988247, 8.83068894]
[10.07690977]
[10.07690977, 11.5386728]
[11.5386728, 12.01214112, 12.13307653]
[12.01214112, 12.13307653]
In het algemeen kan de raamlengte verschillen van 2.
Hoe kan je dit doen? 
Ik denk dat je increment bedoelde op basis van "Voor elk venster met een lengte van 2 seconden beginnend bij een tweede grens" en niet overlappen. Voor intervallen van twee seconden is het hetzelfde, maar aangezien u de lengte wilt variëren, is een overlapping van één seconde 0-3, 2-5, 4-7, maar een toename betekent 0-3, 1-4, 2- 5. Het was echter interessant om voor beide gevallen oplossingen te bedenken.
Ervan uitgaande dat L is gesorteerd en alle elementen positief zijn en de tweede intervallen allemaal beginnen met gehele getallen, kunnen we deze methode gebruiken:
wiskunde importeren
uit collecties import defaultdict
L = [0.10218048, 1.20851996, 1.46800021, 1.73429061, 2.71525848,
3.14781922, 3.63637958, 5.11147358, 5.97497864, 6.35469013,
6.80623747, 6.99571917, 7.65215123, 7.86108352, 8.52988247,
8.83068894, 10.07690977, 11.53867284, 12.01214112, 12.13307653]
my_ranges = defaultdict (lijst)
interval_width = 2
voor x in L:
upper_bound = math.ceil (x)
lower_bound = upper_bound - interval_width
lower_bound = max (0, lower_bound)
voor y in bereik (ondergrens, bovengrens):
mijn_bereik [y] .append (x)
voor a in gesorteerd (mijn_bereik):
print (mijn_bereik [a])
Ik weet niet of je wilt zien of er lege bereiken zijn. Maar de defaultdict drukt desgewenst ook lege bereiken af. Gebruik deze regel in plaats van "voor een gesorteerd":
voor een binnen bereik (min (mijn_bereik), max (mijn_bereik) + 1):
Als je de bereiken 0-3, 2-5, 4-7 wilde, werkt dit:
wiskunde importeren
uit collecties import defaultdict
L = [0.10218048, 1.20851996, 1.46800021, 1.73429061, 2.71525848,
3.14781922, 3.63637958, 5.11147358, 5.97497864, 6.35469013,
6.80623747, 6.99571917, 7.65215123, 7.86108352, 8.52988247,
8.83068894, 10.07690977, 11.53867284, 12.01214112, 12.13307653]
interval_width = 2
my_ranges_2 = defaultdict (lijst)
voor x in L:
sure_in = (x // (interval_width - 1)) * (interval_width - 1) # laagste veelvoud van interval_width onder x zal altijd in
#print ("Toevoegen", x, "aan", zeker_in)
my_ranges_2 [zeker_in] .append (x)
if x  = 0: # bijvoorbeeld, als x 2,3 is en we hebben 0,3 2,5 enz. ... moeten we dit dubbele geval opvangen. Ik neem aan dat de vensterlengtes gehele getallen zijn, en zo niet, dan hebben we nog veel meer te doen, omdat het getal in meer dan één array kan voorkomen. Misschien kunnen we een while-lus hebben, oplopend met (interval_width - 1)
#print ("++ Toevoegen", x, "aan", zeker_in - interval_breedte + 1)
my_ranges_2 [definitief_in - interval_breedte + 1] .append (x)
voor a in gesorteerd (my_ranges_2):
print (a, my_ranges_2 [a])
# print (my_ranges_2 [a])
Ik vermoed dat er enkele details zijn die ik ben vergeten, maar hopelijk kun je interval_width naar behoefte verdraaien om er zeker van te zijn dat mijn code doet wat je had gehoopt en me te laten weten wat je precies nodig hebt.
|
Een mogelijke oplossing die ik kan voorstellen is in zekere zin "efficiënt", dat het slechts één keer door de invoergegevens wordt herhaald en geen afhankelijkheden heeft. De kosten zijn natuurlijk dat het in pure python is geschreven (er is mogelijk meer geoptimaliseerde code) en dat het meer trackingvariabelen introduceert om herhaling te voorkomen (en dus minder pythonisch is).
def sliding_window (data, duration, start = 0, overlap = 1):
resultaat = []
data_idx = 0
result_idx = 0
upper = start + duur
lager = start
next_lower = bovenste - overlap
# innerlijke helper om lege binnenlijsten op te vullen tot aan ons invoegpunt en insert
def pad_and_append (at):
while len (resultaat) <= op:
result.append ([])
resultaat [at] .append (data [data_idx])
# itereren door invoergegevens
while data_idx  a:
als x  = l [0]) & (L  = i) & (L